%This script creates a pseudo random binary sequence and creates a header
%with the encoded data and methods required to interface with the PRBS
%data.
%
%This code requires the system identification toolbox to work properly.
%
%Pavlo Manovi - 2014 NASA Ames - Code TI - IRG - DTRT

pre = [ ...
    '/**                                                            \r\n'...
    ' * @file   PRBSData.h                                          \r\n'...
    ' * @author Pavlo Manovi                                        \r\n'...
    ' * @brief  PRBS gentle on memory in byte aligned space         \r\n'...
    ' *                                                             \r\n'...
    ' * This library provides the data and the methods required to  \r\n'...
    ' * interact with a pseudo random binary sequence in a memory   \r\n'...
    ' * efficient way.  It was fully generated by PRBSGenC99, a     \r\n'...
    ' * script which should be found in this directory.  If not,    \r\n'...
    ' * see:  (insert github address here, later, Pavlo).           \r\n'...
    ' *                                                             \r\n'...
    ' */                                                            \r\n'...
    ' \r\n\r\n'...
    '#include <stdint.h>                                            \r\n'...
    '#include <Generic.h>                                           \r\n'...
    '#include <xc.h>                                                \r\n'...
    ];


post = [ ...
        '/**                                                               \r\n'...
        ' *                                                                \r\n'...
        ' * Put some documentation here eventually.                        \r\n'...
        ' *                                                                \r\n'...
        ' */                                                               \r\n'...
        'uint8_t GetState(uint16_t position) {                             \r\n'...
        '	WORD_VAL pm_read;                                              \r\n'...
        '	uint16_t tableOffset;                                          \r\n'...
        '	uint8_t high = position %% 16;                                  \r\n'...
        '                                                                  \r\n'...
        '	TBLPAG = __builtin_tblpage(&PRBS[0]);                      \r\n'...
        '	tableOffset = __builtin_tbloffset(&PRBS[0]);               \r\n'...
        '	pm_read.Val = __builtin_tblrdl(tableOffset + position / 8);\r\n'...
        '                                                                  \r\n'...
        '	if (high > 7) {                                            \r\n'...
        '		if ((((uint8_t) pm_read.byte.HB) & (0x01 << (high - 8)))) {  \r\n'...
        '	        	return (1);				   \r\n'...
        '     		} else {					   \r\n'...
        '       		return (0);				   \r\n'...
        '    		}						   \r\n'...
        '	} else {							   \r\n'...
        '    		if ((((uint8_t) pm_read.byte.LB) & (0x01 << high))) {	   \r\n'...
        '         		return (1);				   \r\n'...
        '     		} else {					   \r\n'...
        '      			return (0);				   \r\n'...
        '     		}						   \r\n'...
        '	}							   \r\n'...
        '}                                                                 \r\n'...
        ];


%Sequence length should be a power of two for fastest FFT operation.
seqLength = 2^16;
assert(mod((seqLength / 8), 2) == 0, 'seqLength must completely fit in a uint8t');

prbs = idinput(seqLength, 'RBS', [0 .005], [0 1]);

headerOutput = fopen('PRBSData.h', 'w');

count = 1;
lineCount = 0;

fprintf(headerOutput, pre);
fprintf(headerOutput, '#define PRBS_SIZE %i\r\n', ceil(seqLength / 8));
fprintf(headerOutput, '#define PRBS_ELEMENTS %i\r\n\r\n\r\n', seqLength);
fprintf(headerOutput, 'uint8_t PRBS[PRBS_SIZE] __attribute__((space(prog))) = {\r\n        ');

while (count <= seqLength)
    if count > 1
        fprintf(headerOutput, ',');
    end
    
    output = 0;
    
    if prbs(count) == 1
       output = output + 1 ;
    end
    if prbs(count + 1) == 1
       output = output + 2  ;
    end
    if prbs(count + 2) == 1
       output = output + 4 ;
    end
    if prbs(count + 3) == 1
       output = output + 8  ;
    end
    if prbs(count + 4) == 1
       output = output + 16;
    end
    if prbs(count + 5) == 1
       output = output + 32;
    end
    if prbs(count + 6) == 1
       output = output + 64;
    end
    if prbs(count + 7) == 1
       output = output + 128;
    end
    
    if lineCount == 9
        lineCount = 0;
        fprintf(headerOutput, '\r\n        ');
    end
    
    fprintf(headerOutput, '0x%02X', output);
    lineCount = lineCount + 1;
    
    count = count + 8;
end

fprintf(headerOutput, '\r\n};\r\n\r\n');
fprintf(headerOutput, post);
fprintf(headerOutput, '\r\n');
fclose(headerOutput);
